/**
 * JZ UnoCSS - 辅助函数模块
 * 提供各种工具和辅助功能
 * @version 1.1.0
 * @author jz
 */

import { generateCSS } from '../core/generator.js';
import { utils } from './utils.js';

/**
 * 生成CSS并写入文件的备用方法
 * @param {string[]} classNames - 类名数组
 * @param {Object} options - 选项
 * @returns {string} CSS内容
 */
export function generateAndWriteCSS(classNames, options = {}) {
    const cssRules = [];
    const processedClasses = new Set();
    
    // 去重
    const uniqueClassNames = [...new Set(classNames)];
    
    for (const className of uniqueClassNames) {
        if (processedClasses.has(className)) {
            continue;
        }
        
        try {
            const styles = generateCSS(className, options);
            if (styles && typeof styles === 'object' && Object.keys(styles).length > 0) {
                // 生成CSS规则
                const selector = utils.encodeClassNameForUvue(className);
                const cssProps = Object.entries(styles)
                    .filter(([prop]) => !prop.startsWith('__'))
                    .map(([prop, value]) => `  ${prop}: ${value};`)
                    .join('\n');
                
                const cssRule = `.${selector} {\n${cssProps}\n}`;
                cssRules.push(cssRule);
            } else if (typeof styles === 'string') {
                // 直接是CSS字符串（如条件编译CSS）
                cssRules.push(styles);
            }
            
            processedClasses.add(className);
        } catch (error) {
            console.warn(`[JZ UnoCSS] 生成CSS失败 ${className}:`, error.message);
        }
    }
    
    const cssContent = cssRules.join('\n\n') + '\n';
    
    // 尝试写入文件
    try {
        const outputPath = options.cssOutputPath || 'uni_modules/jz-unocss-uvue/main.css';
        updateCSSFile(outputPath, cssContent);
    } catch (error) {
        console.error('[JZ UnoCSS] ❌ 备用CSS写入失败:', error.message);
    }
    
    return cssContent;
}

/**
 * ESM环境下的CSS文件更新函数
 * @param {string} outputPath - 输出路径
 * @param {string} cssContent - CSS内容
 * @returns {boolean} 是否成功写入
 */
export function updateCSSFileESM(outputPath, cssContent) {
    try {
        // 尝试使用动态导入加载fs模块
        const fs = require('fs');
        const path = require('path');
        
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(outputPath, cssContent, 'utf-8');
        
        return true;
    } catch (error) {
        // 如果无法使用fs模块，尝试使用生成脚本
        try {
            // 在Node.js环境中执行脚本
            // 使用Function构造函数替代eval以避免构建工具警告
            try {
                const scriptFunction = new Function('fs', 'path', 'outputPath', 'cssContent', `
                    const dir = path.dirname(outputPath);
                    if (!fs.existsSync(dir)) {
                        fs.mkdirSync(dir, { recursive: true });
                    }
                    fs.writeFileSync(outputPath, cssContent, 'utf-8');
                `);
                
                const fs = require('fs');
                const path = require('path');
                scriptFunction(fs, path, outputPath, cssContent);
            } catch (functionError) {
                // 如果Function构造函数也失败，直接使用模块
                const fs = require('fs');
                const path = require('path');
                
                const dir = path.dirname(outputPath);
                if (!fs.existsSync(dir)) {
                    fs.mkdirSync(dir, { recursive: true });
                }
                
                fs.writeFileSync(outputPath, cssContent, 'utf-8');
            }
            
            return true;
        } catch (evalError) {
            console.error('[JZ UnoCSS] ❌ ESM环境CSS更新失败:', error.message);
            return false;
        }
    }
}

/**
 * 通用的CSS文件更新函数
 * @param {string} outputPath - 输出路径
 * @param {string} cssContent - CSS内容
 * @returns {boolean} 是否成功写入
 */
export function updateCSSFile(outputPath, cssContent) {
    try {
        // 尝试使用Node.js fs模块
        const fs = require('fs');
        const path = require('path');
        
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(outputPath, cssContent, 'utf-8');
        return true;
    } catch (error) {
        console.warn('[JZ UnoCSS] 写入CSS文件时出错:', error.message);
        return false;
    }
}

/**
 * 检查文件是否存在
 * @param {string} filePath - 文件路径
 * @returns {boolean} 文件是否存在
 */
export function fileExists(filePath) {
    try {
        const fs = require('fs');
        return fs.existsSync(filePath);
    } catch (error) {
        return false;
    }
}

/**
 * 读取文件内容
 * @param {string} filePath - 文件路径
 * @returns {string|null} 文件内容或null
 */
export function readFileContent(filePath) {
    try {
        const fs = require('fs');
        if (fs.existsSync(filePath)) {
            return fs.readFileSync(filePath, 'utf-8');
        }
        return null;
    } catch (error) {
        console.warn(`[JZ UnoCSS] 读取文件失败 ${filePath}:`, error.message);
        return null;
    }
}

/**
 * 写入文件内容
 * @param {string} filePath - 文件路径
 * @param {string} content - 文件内容
 * @returns {boolean} 是否成功写入
 */
export function writeFileContent(filePath, content) {
    try {
        const fs = require('fs');
        const path = require('path');
        
        // 确保目录存在
        const dir = path.dirname(filePath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }
        
        // 写入文件
        fs.writeFileSync(filePath, content, 'utf-8');
        return true;
    } catch (error) {
        console.error(`[JZ UnoCSS] 写入文件失败 ${filePath}:`, error.message);
        return false;
    }
}

/**
 * 防抖函数
 * @param {Function} func - 要防抖的函数
 * @param {number} wait - 等待时间（毫秒）
 * @returns {Function} 防抖后的函数
 */
export function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

/**
 * 节流函数
 * @param {Function} func - 要节流的函数
 * @param {number} limit - 时间限制（毫秒）
 * @returns {Function} 节流后的函数
 */
export function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => inThrottle = false, limit);
        }
    };
}

/**
 * 深度合并对象
 * @param {Object} target - 目标对象
 * @param {...Object} sources - 源对象
 * @returns {Object} 合并后的对象
 */
export function deepMerge(target, ...sources) {
    if (!sources.length) return target;
    const source = sources.shift();

    if (isObject(target) && isObject(source)) {
        for (const key in source) {
            if (isObject(source[key])) {
                if (!target[key]) Object.assign(target, { [key]: {} });
                deepMerge(target[key], source[key]);
            } else {
                Object.assign(target, { [key]: source[key] });
            }
        }
    }

    return deepMerge(target, ...sources);
}

/**
 * 检查是否为对象
 * @param {*} item - 要检查的项
 * @returns {boolean} 是否为对象
 */
function isObject(item) {
    return item && typeof item === 'object' && !Array.isArray(item);
}

/**
 * 格式化文件大小
 * @param {number} bytes - 字节数
 * @returns {string} 格式化后的大小
 */
export function formatFileSize(bytes) {
    if (bytes === 0) return '0 Bytes';
    
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

/**
 * 检查并自动生成CSS文件
 * @param {string} cssPath - CSS文件路径
 * @param {Object} config - 配置对象
 * @param {boolean} force - 是否强制生成
 * @returns {boolean} 是否生成了CSS
 */
export function checkAndAutoGenerateCSS(cssPath, config = {}, force = false) {
    try {
        const fs = require('fs');
        
        // 如果文件不存在或强制生成，则创建基础CSS文件
        if (!fs.existsSync(cssPath) || force) {
            const baseCSS = `/* JZ UnoCSS - Auto Generated CSS */
/* 此文件由 jz-unocss-uvue 插件自动生成，请勿手动修改 */
/* 您可以在 main.uts 中导入此文件：import './uni_modules/jz-unocss-uvue/main.css' */

`;
            
            const path = require('path');
            const dir = path.dirname(cssPath);
            if (!fs.existsSync(dir)) {
                fs.mkdirSync(dir, { recursive: true });
            }
            
            fs.writeFileSync(cssPath, baseCSS, 'utf-8');
            return true;
        }
        
        return false;
    } catch (error) {
        console.warn('[JZ UnoCSS] 自动生成CSS失败:', error.message);
        return false;
    }
}

/**
 * 验证是否为有效的UnoCSS类名
 * @param {string} className - 类名
 * @returns {boolean} 是否有效
 */
export function isValidUnoClass(className) {
    if (!className || typeof className !== 'string') {
        return false;
    }
    
    // 基本的类名格式验证
    const validPatterns = [
        /^[a-zA-Z][\w-]*$/, // 普通类名
        /^[a-zA-Z][\w-]*-\d+$/, // 带数字的类名
        /^[a-zA-Z][\w-]*-\[[^\]]+\]$/, // 方括号语法
        /^[a-zA-Z][\w-]*-#[0-9a-fA-F]+$/, // 颜色值
    ];
    
    return validPatterns.some(pattern => pattern.test(className));
}

// 注意：所有函数都已在定义时使用 export 导出，无需重复导出 